<?php
use think\Model;
/**
 * 支付 逻辑定义
 * Class
 * @package Home\Payment
 */

class weixin extends Model
{
    public $tableName = 'plugin'; // 插件表
    public $alipay_config = array();// 支付宝支付配置参数

    /**
     * 析构流函数
     */
    public function  __construct($config) {
        parent::__construct();
        require_once("lib/WxPay.Api.php"); // 微信扫码支付demo 中的文件
        require_once("lib/WxPay.Notify.php"); // 回调
        require_once("example/WxPay.NativePay.php");
        require_once("example/WxPay.JsApiPay.php");

        WxPayConfig::$appid = $config['AppID']; // * APPID：绑定支付的APPID（必须配置，开户邮件中可查看）
        WxPayConfig::$mchid = $config['Mchid']; // * MCHID：商户号（必须配置，开户邮件中可查看）
        WxPayConfig::$key = $config['Key']; // KEY：商户支付密钥，参考开户邮件设置（必须配置，登录商户平台自行设置）
        WxPayConfig::$appsecret = $config['AppSecret']; // 公众帐号secert（仅JSAPI支付的时候需要配置)，
    }

//    /**
//     * 服务器点对点响应操作给支付接口方调用
//     *
//     */
//    function response(){
//        // 给微信返回支付状态值
//        $notify = new \WxPayNotify();
//        // 返回状态
//        $notify->Handle(false);
//
//    }

//    /**
//     * 页面跳转响应操作给支付接口方调用
//     */
//    function respond2(){
//        // 微信扫码支付这里没有页面返回
//    }


    function getJsapiParams($orderInfo){


        //①、获取用户openid
        $tools = new JsApiPay();
        //②、统一下单
        $attach = json_encode($orderInfo['attach']);
        $input = new WxPayUnifiedOrder();
        $input->SetBody($orderInfo['body']);
        $input->SetOut_trade_no($orderInfo['orderNo']);
        $input->SetTotal_fee($orderInfo['orderPrice'] * 100);
        $input->SetAttach($attach);
        $input->SetNotify_url($orderInfo['notifyUrl']);
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($orderInfo['openid']);

        $order2 = WxPayApi::unifiedOrder($input);
        if (isset($order2['return_code']) && $order2['return_code'] == 'FAIL') {
            return $order2;
        }

        $jsApiParameters = $tools->GetJsApiParameters($order2);
        return json_decode($jsApiParameters, true);

    }

    function transfer($orderInfo){
        //CA证书及支付信息
        $wxchat['appid'] = WxPayConfig::$appid;
        $wxchat['mchid'] = WxPayConfig::$mchid;
        $wxchat['api_cert'] = __DIR__ . 'payment/weixin/cert/apiclient_cert.pem';
        $wxchat['api_key'] = __DIR__ . 'payment/weixin/cert/apiclient_key.pem';
        $wxchat['api_ca'] = __DIR__ . 'payment/weixin/cert/rootca.pem';
        $webdata = array(
            'mch_appid' => $wxchat['appid'],
            'mchid'     => $wxchat['smchid'],
            'nonce_str' => md5(time()),
            //'device_info' => '1000',
            'partner_trade_no'=> $orderInfo['payOrderNo'], //商户订单号，需要唯一
            'openid' => $orderInfo['openid'],//转账用户的openid
            'check_name'=> 'NO_CHECK', //OPTION_CHECK不强制校验真实姓名, FORCE_CHECK：强制 NO_CHECK：
            //'re_user_name' => 'jorsh', //收款人用户姓名
            'amount' => $orderInfo['orderPrice'] * 100, //付款金额单位为分
            'desc'   => $orderInfo['orderDesc'],
            'spbill_create_ip' => request()->ip(),
        );
        foreach ($webdata as $k => $v) {
            $tarr[] =$k.'='.$v;
        }
        sort($tarr);
        $sign = implode($tarr, '&');
        $sign .= '&key='.WxPayConfig::$key;
        $webdata['sign']=strtoupper(md5($sign));
        $wget = $this->array2xml($webdata);
        $pay_url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
        $res = $this->http_post($pay_url, $wget, $wxchat);
        if(!$res){
            return array('status'=>1, 'msg'=>"Can't connect the server" );
        }
        $content = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
        if(strval($content->return_code) == 'FAIL'){
            return array('status'=>1, 'msg'=>strval($content->return_msg));
        }
        if(strval($content->result_code) == 'FAIL'){
            return array('status'=>1, 'msg'=>strval($content->err_code),':'.strval($content->err_code_des));
        }
        $rdata = array(
            'mch_appid'        => strval($content->mch_appid),
            'mchid'            => strval($content->mchid),
            'device_info'      => strval($content->device_info),
            'nonce_str'        => strval($content->nonce_str),
            'result_code'      => strval($content->result_code),
            'partner_trade_no' => strval($content->partner_trade_no),
            'payment_no'       => strval($content->payment_no),
            'payment_time'     => strval($content->payment_time),
        );
        return $rdata;
    }

    /**
     * 将一个数组转换为 XML 结构的字符串
     * @param array $arr 要转换的数组
     * @param int $level 节点层级, 1 为 Root.
     * @return string XML 结构的字符串
     */
    function array2xml($arr, $level = 1) {
        $s = $level == 1 ? "<xml>" : '';
        foreach($arr as $tagname => $value) {
            if (is_numeric($tagname)) {
                $tagname = $value['TagName'];
                unset($value['TagName']);
            }
            if(!is_array($value)) {
                $s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>";
            } else {
                $s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>";
            }
        }
        $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
        return $level == 1 ? $s."</xml>" : $s;
    }

    function http_post($url, $param, $wxchat) {
        $oCurl = curl_init();
        if (stripos($url, "https://") !== FALSE) {
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
        }
        if (is_string($param)) {
            $strPOST = $param;
        } else {
            $aPOST = array();
            foreach ($param as $key => $val) {
                $aPOST[] = $key . "=" . urlencode($val);
            }
            $strPOST = join("&", $aPOST);
        }
        curl_setopt($oCurl, CURLOPT_URL, $url);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($oCurl, CURLOPT_POST, true);
        curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
        if($wxchat){
            curl_setopt($oCurl,CURLOPT_SSLCERT,dirname(THINK_PATH).$wxchat['api_cert']);
            curl_setopt($oCurl,CURLOPT_SSLKEY,dirname(THINK_PATH).$wxchat['api_key']);
            curl_setopt($oCurl,CURLOPT_CAINFO,dirname(THINK_PATH).$wxchat['api_ca']);
        }
        $sContent = curl_exec($oCurl);
        $aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        if (intval($aStatus["http_code"]) == 200) {
            return $sContent;
        } else {
            return false;
        }
    }

    // 支付金额原路退还
    public function paymentRefund($orderInfo){
        if(!empty($orderInfo["orderTransactionId"])){
            $input = new WxPayRefund();
            $input->SetTransaction_id($orderInfo["orderTransactionId"]);
            $input->SetTotal_fee($orderInfo["orderActualPrice"] * 100);
            $input->SetRefund_fee($orderInfo["orderRefundPrice"] * 100);
            $input->SetOut_refund_no($orderInfo['orderRefundNo']);
            $input->SetOp_user_id(WxPayConfig::$mchid);
            return WxPayApi::refund($input);
        }else{
            return false;
        }
    }

}